package utils

import (
	"alertmanagerWebhook/config"
	"alertmanagerWebhook/global"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type PrometheusUtil struct {
	client *http.Client
}

func NewPrometheusUtil() *PrometheusUtil {
	return &PrometheusUtil{
		client: &http.Client{Timeout: 5 * time.Second},
	}
}

// 从generatorURL查询当前值
func (p *PrometheusUtil) QueryCurrentValue(generatorURL string, alert config.Alert) (string, error) {
	if generatorURL == "" {
		return "", fmt.Errorf("empty generator URL")
	}

	// 使用配置的Prometheus地址替换URL中的主机部分
	if global.Config.System.PrometheusAddr != "" {
		u, err := url.Parse(generatorURL)
		if err != nil {
			return "", fmt.Errorf("parse URL failed: %w", err)
		}
		generatorURL = strings.Replace(generatorURL, u.Host, global.Config.System.PrometheusAddr, 1)
	}

	// 解析URL获取查询表达式
	u, err := url.Parse(generatorURL)
	if err != nil {
		return "", fmt.Errorf("parse URL failed: %w", err)
	}

	expr := u.Query().Get("g0.expr")
	if expr == "" {
		return "", fmt.Errorf("no query expression found in URL")
	}

	// 构建Prometheus API请求
	baseURL := strings.Replace(generatorURL, "/graph", "", 1)
	u, err = url.Parse(baseURL)
	if err != nil {
		return "", fmt.Errorf("parse base URL failed: %w", err)
	}

	// 构建Prometheus API请求时添加时间范围参数
	apiURL := fmt.Sprintf("%s://%s/api/v1/query", u.Scheme, u.Host)
	req, err := http.NewRequest("GET", apiURL, nil)
	if err != nil {
		return "", fmt.Errorf("create request failed: %w", err)
	}

	q := req.URL.Query()
	q.Add("query", expr)
	// 添加时间参数，使用告警触发时间
	if !alert.StartsAt.IsZero() {
		q.Add("time", alert.StartsAt.Format(time.RFC3339))
	}
	req.URL.RawQuery = q.Encode()
	// 添加日志打印最终查询地址
	global.Logger.Debugf("Prometheus查询地址: %s", req.URL.String())

	// 执行查询
	resp, err := p.client.Do(req)
	if err != nil {
		return "", fmt.Errorf("query failed: %w", err)
	}
	defer resp.Body.Close()

	// 替换为 io.ReadAll
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("read response failed: %w", err)
	}

	// 解析响应
	var result config.PrometheusQueryResult
	if err := json.Unmarshal(body, &result); err != nil {
		return "", fmt.Errorf("parse response failed: %w", err)
	}

	if result.Status != "success" || len(result.Data.Result) == 0 {
		return "", fmt.Errorf("no valid data in response")
	}

	// 尝试匹配告警标签与查询结果
	/*
		- 方法会严格匹配告警的多个标签（alertname、instance、severity、job）
		- 只有所有标签都匹配的结果才会被返回
		- 如果没有完全匹配的结果，会返回第一个结果并记录警告
	*/
	for _, res := range result.Data.Result {
		match := true

		// Check Alertname
		if res.Metric["alertname"] != alert.Labels.Alertname {
			match = false
		}

		// Check Instance
		if res.Metric["instance"] != alert.Labels.Instance {
			match = false
		}

		// Check Severity
		if res.Metric["severity"] != alert.Labels.Severity {
			match = false
		}

		// Check other common labels
		if res.Metric["job"] != alert.Labels.Job {
			match = false
		}

		if match && len(res.Value) >= 2 {
			if valueStr, ok := res.Value[1].(string); ok {
				global.Logger.Infof("从Prometheus查询到的值: %s (表达式: %s, 匹配标签: alertname=%s, instance=%s)",
					valueStr, expr, alert.Labels.Alertname, alert.Labels.Instance)
				return valueStr, nil
			}
		}
	}

	// 如果没有完全匹配的结果，返回第一个结果
	if len(result.Data.Result[0].Value) >= 2 {
		if valueStr, ok := result.Data.Result[0].Value[1].(string); ok {
			global.Logger.Warnf("未找到完全匹配的结果，返回第一个值: %s (表达式: %s)", valueStr, expr)
			return valueStr, nil
		}
	}

	return "", fmt.Errorf("invalid value format")
}
